package com.autonavi.yunda.yunji.core.service;

import com.autonavi.yunda.yunji.common.exception.AmapPreconditions;
import com.autonavi.yunda.yunji.core.model.dto.DatasourceConfigDTO;
import com.autonavi.yunda.yunji.core.model.dto.DatasourceProjectMappingDTO;
import com.autonavi.yunda.yunji.core.model.dto.ProjectDTO;
import com.autonavi.yunda.yunji.core.model.mappers.DatasourceProjectMappingMapper;
import com.autonavi.yunda.yunji.core.model.mappers.ProjectMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author sunzhenbang
 */
@Repository
public class DatasourceProjectMappingService {
    @Resource
    private DatasourceProjectMappingMapper datasourceProjectMappingMapper;
    @Resource
    private ProjectMapper projectMapper;

    public Integer insertBatchSomeColumn(List<DatasourceProjectMappingDTO> datasourceProjectMappingDTOList) {
        return datasourceProjectMappingMapper.insertBatchSomeColumn(datasourceProjectMappingDTOList);
    }

    public void deleteByDatasourceId(Long datasourceId) {
        datasourceProjectMappingMapper.deleteByDatasourceId(datasourceId);
    }

    public void deleteBatchIds(List<Long> ids) {
        datasourceProjectMappingMapper.deleteBatchIds(ids);
    }

    public List<String> listDatasourceIdsByPid(String projectId) {
        return datasourceProjectMappingMapper.listDatasourceIdsByPid(projectId);
    }

    public List<DatasourceProjectMappingDTO> listByProjectIds(List<String> projectIds) {
        if (CollectionUtils.isEmpty(projectIds)) {
            return new ArrayList<>();
        }
        return datasourceProjectMappingMapper.listByProjectIds(projectIds);
    }

    public List<DatasourceProjectMappingDTO> listDatasourceByDbId(Long id) {
        UpdateWrapper<DatasourceProjectMappingDTO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("datasource_id", id);
        return datasourceProjectMappingMapper.selectList(updateWrapper);
    }

    public void updateMapping(Long datasourceId, List<String> syncProjectIds, String operator) {
        List<String> updateProjectIds = projectMapper.selectList(new QueryWrapper<ProjectDTO>().in("project_id", syncProjectIds))
                .stream().map(ProjectDTO::getProjectId).collect(Collectors.toList());
        AmapPreconditions.checkArgumentForUser(!CollectionUtils.isEmpty(updateProjectIds), "数据源关联的项目不存在");
        List<DatasourceProjectMappingDTO> datasourceProjectList = listDatasourceByDbId(datasourceId);
        List<Long> deleteIds = new ArrayList<>();
        for (DatasourceProjectMappingDTO datasourceProjectMappingDTO : datasourceProjectList) {
            if (!updateProjectIds.contains(datasourceProjectMappingDTO.getProjectId())) {
                Long id = datasourceProjectMappingDTO.getId();
                deleteIds.add(id);
            }
        }
        if (!CollectionUtils.isEmpty(deleteIds)) {
            deleteBatchIds(deleteIds);
        }
        List<String> addProjectIds = new ArrayList<>(updateProjectIds);
        datasourceProjectList.forEach(dp -> addProjectIds.removeIf(pid -> pid.equals(dp.getProjectId())));
        if (!CollectionUtils.isEmpty(addProjectIds)) {
            insertBatchSomeColumn(toDatasourceProjectMappingDTOList(datasourceId, addProjectIds, operator));
        }
    }

    public List<DatasourceProjectMappingDTO> toDatasourceProjectMappingDTOList(Long datasourceId, List<String> projectIds, String operator) {
        ArrayList<DatasourceProjectMappingDTO> datasourceProjectList = new ArrayList<>();
        projectIds.forEach(projectId -> datasourceProjectList.add(
                DatasourceProjectMappingDTO.builder()
                        .datasourceId(datasourceId)
                        .projectId(projectId).createUser(operator).updateUser(operator)
                        .createTime(new Timestamp(System.currentTimeMillis()))
                        .updateTime(new Timestamp(System.currentTimeMillis()))
                        .build()
        ));
        return datasourceProjectList;
    }

    /**
     * 本地化/离线方案-获取导出项目的数据源列表
     * @param projectIds    项目ID列表
     * @return  数据源列表
     */
    public List<DatasourceConfigDTO> listDatasourceByProjectIds(List<String> projectIds) {
        if (CollectionUtils.isEmpty(projectIds)) {
            return new ArrayList<>();
        }
        return datasourceProjectMappingMapper.listDatasourceByProjectIds(projectIds);
    }
}
